// $URL: http://mingw-lib.googlecode.com/svn/trunk/c-drive/mingw-lib/product/box/yt_new/yt_rec.cpp $
// $Rev: 861 $
// $Author: akio.miyoshi@gmail.com $
// $Date:: 2013-08-07 05:28:50 +0000#$

#include "yt_rec.h"
#include "yt_web.h"
#include <QtCore>
#include <QVariant>
#include <QtSql>
#include <QtXml>
#include "xmlutil.h"
#include "env.h"

T_Video::T_Video(QObject *parent)
	: QObject(parent), deleted(false)
{
}

static QString s_toJSON_sanitizeString( QString str )
{
	////qDebug() << "s_toJSON_sanitizeString()" << str;
	str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) );
	str.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
	str.replace( QLatin1String( "\b" ), QLatin1String( "\\b" ) );
	str.replace( QLatin1String( "\f" ), QLatin1String( "\\f" ) );
	str.replace( QLatin1String( "\n" ), QLatin1String( "\\n" ) );
	str.replace( QLatin1String( "\r" ), QLatin1String( "\\r" ) );
	str.replace( QLatin1String( "\t" ), QLatin1String( "\\t" ) );
	QString v_result = QString( QLatin1String( "\"%1\"" ) ).arg( str );
	///qDebug() << v_result;
	return v_result;
}

QString T_Video::toJSON() const
{
	QString v_json = "{";
	int v_count = 0;
	for(int i=0; i<this->metaObject()->propertyCount(); i++)
	{
		QMetaProperty v_prop = this->metaObject()->property(i);
		if(strcmp(v_prop.name(), "objectName")==0) continue;
		QString v_name = v_prop.name();
		QVariant v_value = this->property(v_prop.name());
		QVariant::Type v_type = v_value.type();
		//QString v_exp = "undefined";
		QString v_exp = "null";
		switch(v_type)
		{
		case QVariant::Int:
		case QVariant::LongLong:
			v_exp = v_value.toString();
			break;
		case QVariant::Double:
			v_exp = v_value.toString();
			break;
		case QVariant::Bool:
			v_exp = v_value.toString();
			break;
		case QVariant::String:
			v_exp = s_toJSON_sanitizeString(v_value.toString());
			break;
		case QVariant::DateTime:
            { QLocale v_locale( QLocale::C );
                // QDateTime::toString() is locale dependent.
                //v_exp = QString("\"%1 GMT\"").arg( v_locale.toString(v_value.toDateTime(), "MMM d,yyyy hh:mm:ss"));
                v_exp = QString("\"%1 GMT\"").arg( v_locale.toString(v_value.toDateTime(), "d MMM yyyy hh:mm:ss"));
            }
			break;
        default:
            v_exp = "null";
		}
		v_count++;
		if(v_count>1) v_json += ", ";
		v_json += QString("\"%1\":%2").arg(v_name).arg(v_exp);
	}
	v_json += "}";
	return v_json;
}

QString T_Video::get_icon_url() const
{
	return YtWeb::getUrlForVideoIcon(id);
}

void T_VideoList::set_domain(QString a)
{
	m_domain = a;
	qDebug() << "T_VideoList::set_domain(): [m_domain]" << m_domain;
	YtManager::dbPrepareTable(get_tbl_name());
	YtManager::dbPrepareTable(get_tbl_name()+"_old");
    QSqlQuery v_query;
    QString v_sql = QString(
            "create table yt_name_id("
            " user_uri text"
            ",user_id text"
            ",primary key(user_uri)"
            ")"
            )
            ;
    qDebug() << v_sql;
    bool v_query_success = v_query.exec(v_sql);
    reload();
}

void T_VideoList::reload()
{
	QString v_tbl_name = m_domain;
	v_tbl_name.replace(":", "_");
	qDebug() << "T_VideoList::reload(): [m_domain]" << m_domain;
	qDebug() << "T_VideoList::reload(): [v_tbl_name]" << v_tbl_name;
	//if(m_domain.startsWith("fv:"))
	{
		YtManager::dbVideoListLoad(this, v_tbl_name, this->m_keyword);
		sort_internal(m_sort_type);
		emit updated();
	}
}

void T_VideoList::reload2()
{
    this->clear();
    QString v_tbl_name = m_domain;
    v_tbl_name.replace(":", "_");
    qDebug() << "T_VideoList::reload2(): [m_domain]" << m_domain;
    qDebug() << "T_VideoList::reload2(): [v_tbl_name]" << v_tbl_name;
    YtManager::dbVideoListLoad(this, v_tbl_name, this->m_keyword);
}

T_Video *T_VideoList::append()
{
	T_Video *v_record = new T_Video(this);
	m_list.append(v_record);
	return v_record;
}

void T_VideoList::append(T_VideoList *a_video_list)
{
	for(int i=0; i<a_video_list->size(); i++)
	{
		T_Video *v_rec = this->append();
		T_Video *v_src = a_video_list->value(i);
		for(int j=0; j<v_rec->metaObject()->propertyCount(); j++)
		{
			QMetaProperty v_prop = v_rec->metaObject()->property(j);
			if(v_prop.isWritable())
			{
				v_rec->setProperty(v_prop.name(), v_src->property(v_prop.name()));
			}
		}
	}
}

void T_VideoList::deleteById(QString a_id)
{
	for(int i=0; i<m_list.size(); i++)
	{
		T_Video *v_rec = m_list.value(i);
		if(v_rec->id == a_id)
		{
			v_rec->deleted = true;
		}
	}
}

void T_VideoList::clear()
{
	for(int i=0; i<m_list.size(); i++)
	{
		if(m_list.value(i)) delete m_list.value(i);
	}
	m_list.clear();
}

static bool s_sort_latest(const T_Video *r1, const T_Video *r2)
{
	return r1->pos <= r2->pos;
}

static bool s_sort_waiting(const T_Video *r1, const T_Video *r2)
{
	if(r1->get_view_ts_hour() == r2->get_view_ts_hour())
	{
		return r1->pos <= r2->pos;
	}
	return r1->get_view_ts_hour() >= r2->get_view_ts_hour();
}

static bool s_sort_pubdate(const T_Video *r1, const T_Video *r2)
{
	if(r1->pubdate == r2->pubdate)
	{
		return r1->pos <= r2->pos;
	}
	return r1->pubdate >= r2->pubdate;
}

static bool s_sort_total(const T_Video *r1, const T_Video *r2)
{
	if(r1->view_count == r2->view_count)
	{
		return r1->pos <= r2->pos;
	}
	return r1->view_count >= r2->view_count;
}

static bool s_sort_favorite_total(const T_Video *r1, const T_Video *r2)
{
	if(r1->favorite_count == r2->favorite_count)
	{
		return r1->pos <= r2->pos;
	}
	return r1->favorite_count >= r2->favorite_count;
}

static bool s_sort_delta(const T_Video *r1, const T_Video *r2)
{
	if(r1->get_view_count_diff() == r2->get_view_count_diff())
	{
		return r1->view_count >= r2->view_count;
	}
	return r1->get_view_count_diff() >= r2->get_view_count_diff();
}

static bool s_sort_unit_delta(const T_Video *r1, const T_Video *r2)
{
	double r1_delta = r1->get_view_count_diff();
	if(r1->get_view_ts_hour() != 0) r1_delta /= r1->get_view_ts_hour();
	double r2_delta = r2->get_view_count_diff();
	if(r2->get_view_ts_hour() != 0) r2_delta /= r2->get_view_ts_hour();
	if(r1_delta == r2_delta)
	{
		return r1->view_count >= r2->view_count;
	}
	return r1_delta >= r2_delta;
}

static bool s_sort_favorite_delta(const T_Video *r1, const T_Video *r2)
{
	if(r1->get_favorite_count_diff() == r2->get_favorite_count_diff())
	{
		return r1->favorite_count >= r2->favorite_count;
	}
	return r1->get_favorite_count_diff() >= r2->get_favorite_count_diff();
}

void T_VideoList::sort_internal(QString a_type)
{
	m_sort_type = a_type;
	if(a_type == "latest") qSort(m_list.begin(), m_list.end(), s_sort_latest);
	else if(a_type == "waiting") qSort(m_list.begin(), m_list.end(), s_sort_waiting);
	else if(a_type == "pubdate") qSort(m_list.begin(), m_list.end(), s_sort_pubdate);
	else if(a_type == "total") qSort(m_list.begin(), m_list.end(), s_sort_total);
	else if(a_type == "delta") qSort(m_list.begin(), m_list.end(), s_sort_delta);
	else if(a_type == "unit_delta") qSort(m_list.begin(), m_list.end(), s_sort_unit_delta);
	else if(a_type == "favorite_total") qSort(m_list.begin(), m_list.end(), s_sort_favorite_total);
	else if(a_type == "favorite_delta") qSort(m_list.begin(), m_list.end(), s_sort_favorite_delta);
	emit sig_sort_spec(a_type);
}

void T_VideoList::sort(QString a_type)
{
	sort_internal(a_type);
	emit updated();
}

void YtManager::dbVideoListLoad(T_VideoList *a_result, QString a_tbl_name, QString a_keyword)
{
	qDebug() << "YtManager::dbVideoListLoad()" << a_tbl_name << a_keyword;
	QString v_keyword = a_keyword.trimmed().toUpper();
	a_result->clear();
	QSqlQuery query;
	query.exec(QString("select * from %1 order by pos asc").arg(a_tbl_name));
	while(query.next())
	{
		if(!v_keyword.isEmpty())
		{
			QString v_author = query.value(query.record().indexOf("author")).toString().toUpper();
            QString v_title = query.value(query.record().indexOf("title")).toString().toUpper();
            QString v_id = query.value(query.record().indexOf("id")).toString().toUpper();
            if(!v_author.contains(v_keyword) && !v_title.contains(v_keyword) && !v_id.contains(v_keyword))
			{
				continue;
			}
		}
		T_Video *v_rec = a_result->append();
		for(int i=0; i<v_rec->metaObject()->propertyCount(); i++)
		{
			QMetaProperty v_prop = v_rec->metaObject()->property(i);
			if(strcmp(v_prop.name(), "objectName")==0) continue;
			if(query.record().indexOf(v_prop.name()) == -1) continue;
			v_rec->setProperty(v_prop.name(), query.value(query.record().indexOf(v_prop.name())));
		}
		T_Video v_rec_old;
		if(YtManager::dbVideoSelect(v_rec->id, (a_tbl_name + "_old"), &v_rec_old))
		{
			//[view_count_old]
			v_rec->view_count_old = v_rec_old.view_count;
			//[view_rank_old]
			v_rec->view_rank_old = v_rec_old.view_rank;
			//[view_ts_old]
			v_rec->view_ts_old = v_rec_old.view_ts;
			//[favroite_count_old]
			v_rec->favorite_count_old = v_rec_old.favorite_count;
		}
        if((v_rec->title == "Deleted video")||(v_rec->title == "Private video"))
        {
            v_rec->title = v_rec_old.title;
        }
		qDebug() << v_rec;
	}
}

QDateTime YtManager::parseDateTimeYoutube(QString pubDateStr)
{
    // "2008-03-17T17:42:18.000Z"
    QString v_time1 = QString(pubDateStr);
    v_time1 = v_time1.left(19);
    v_time1.replace("T", " ");
    v_time1.replace("-", "/");
    QDateTime v_result = QDateTime::fromString(v_time1, "yyyy/MM/dd HH:mm:ss");
    return v_result;
}

int YtManager::parseXmlForPlaylistList(QByteArray &xml, QList<RecPlaylist> &result)
{
    result.clear();
    QDomDocument domDocument;
    if(!XmlUtil::setXmlContent(domDocument, xml))
    {
        qDebug() << "xml parse error!";
        return 0;
    }
    // [/feed]
    QDomElement v_root = domDocument.documentElement();

    // [/feed/entry(s)]
    QDomNodeList v_entry_list = v_root.elementsByTagNameNS("http://www.w3.org/2005/Atom", "entry");

    // [/feed/entry]
    for (int i=0; i<v_entry_list.count(); i++)
    {
        RecPlaylist v_rec;
        QDomElement v_entry = v_entry_list.at(i).toElement();
        // [/feed/entry/id]
        QDomNodeList v_id_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "id");
        QDomElement v_id = v_id_list.at(0).toElement();
        v_rec.guid = v_id.text();
        v_rec.id = QString(v_rec.guid);
        v_rec.id.replace("http://gdata.youtube.com/feeds/api/users/akmiyoshi/playlists/", "");
        // [/feed/entry/published]
        QDomNodeList v_published_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "published");
        QDomElement v_published = v_published_list.at(0).toElement();
        v_rec.published = parseDateTimeYoutube(v_published.text());
        // [/feed/entry/title]
        QDomNodeList v_title_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "title");
        QDomElement v_title = v_title_list.at(0).toElement();
        v_rec.title = v_title.text();

        //
        result.append(v_rec);
    }
    return result.size();
}

int YtManager::parseXmlForEntryList(QByteArray &xml, T_VideoList *result, qint64 *totalResultCount, bool resolveUserName)
{
	QDateTime v_now = QDateTime::currentDateTime();
	result->clear();
    QDomDocument domDocument;
    if(!XmlUtil::setXmlContent(domDocument, xml))
    {
        qDebug() << "xml parse error!";
        return 0;
    }
    // [/feed]
    QDomElement v_root = domDocument.documentElement();

    // [/feed/openSearch:totalResults]
    QDomNodeList v_total_results_list = v_root.elementsByTagNameNS("http://a9.com/-/spec/opensearchrss/1.0/", "totalResults");
    QDomElement v_total_results_elem = v_total_results_list.at(0).toElement();
    qint64 v_total_results = v_total_results_elem.text().toLongLong();
    if (totalResultCount)
    {
        (*totalResultCount) = v_total_results;
    }

    // [/feed/openSearch:startIndex]
    QDomNodeList v_start_index_list = v_root.elementsByTagNameNS("http://a9.com/-/spec/opensearchrss/1.0/", "startIndex");
    QDomElement v_start_index_elem = v_start_index_list.at(0).toElement();
    qint64 v_start_index = v_start_index_elem.text().toLongLong();

    // [/feed/entry(s)]
    QDomNodeList v_entry_list = v_root.elementsByTagNameNS("http://www.w3.org/2005/Atom", "entry");

    // [/feed/entry]
    for (int i=0; i<v_entry_list.count(); i++)
    {
		T_Video *v_rec = result->append();
		v_rec->view_ts = v_now;

        QDomElement v_entry = v_entry_list.at(i).toElement();
        // v_rec.pos
		v_rec->pos = v_start_index + i;
		//<yt:position xmlns:yt="http://gdata.youtube.com/schemas/2007">20</yt:position>
		QDomNodeList v_pos_list = v_entry.elementsByTagNameNS("http://gdata.youtube.com/schemas/2007", "position");
		if(v_pos_list.size() > 0)
		{
			//<yt:position> は再生リストのビデオ一覧にのみ含まれる
			QDomElement v_pos_elem = v_pos_list.at(0).toElement();
			v_rec->pos = v_pos_elem.text().toInt();
		}
		// [/feed/entry/id(guid)]
        QDomNodeList v_id_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "id");
        QDomElement v_id = v_id_list.at(0).toElement();
		v_rec->guid = v_id.text();
        // [/feed/entry/id(id)]
		if (v_rec->guid.startsWith("http://gdata.youtube.com/feeds/api/videos/"))
        {
			v_rec->id = v_rec->guid;
			v_rec->id.replace("http://gdata.youtube.com/feeds/api/videos/", "");
        }
        else
		if (v_rec->guid.startsWith("http://gdata.youtube.com/feeds/api/playlists/"))
        {
            QDomNodeList v_link_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "link");
            for (int j=0; j<v_link_list.size(); j++)
            {
                QDomElement v_link = v_link_list.at(j).toElement();
                if (v_link.attribute("href").startsWith("http://www.youtube.com/watch?v="))
                {
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
                    QUrlQuery v_href_url(v_link.attribute("href"));
#else
                    QUrl v_href_url;
                    v_href_url.setUrl(v_link.attribute("href"));
#endif
					v_rec->id = v_href_url.queryItemValue("v");
					qDebug() << v_rec->id;
                    break;
                }
            }
        }
        // [/feed/entry/published]
        QDomNodeList v_published_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "published");
        QDomElement v_published = v_published_list.at(0).toElement();
		v_rec->pubdate = parseDateTimeYoutube(v_published.text());

        // [/feed/entry/title]
        QDomNodeList v_title_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "title");
        QDomElement v_title = v_title_list.at(0).toElement();
		v_rec->title = v_title.text();

		// [/feed/entry/author]
		QDomElement v_author = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "author").at(0).toElement();
		QDomElement v_author_name = v_author.elementsByTagNameNS("http://www.w3.org/2005/Atom", "name").at(0).toElement();
		v_rec->author = v_author_name.text();
        if(resolveUserName)
        {
            QDomElement v_author_uri = v_author.elementsByTagNameNS("http://www.w3.org/2005/Atom", "uri").at(0).toElement();
            v_rec->author_uri = v_author_uri.text();
            if(v_rec->author_uri.startsWith("http://gdata.youtube.com/feeds/api/users/"))
            {
                v_rec->author_uri.replace("http://gdata.youtube.com/feeds/api/users/", "");
            }
            qDebug() << "[v_rec->author_uri]" << v_rec->author_uri;
            static QSqlQuery *v_query = NULL;
            if(!v_query)
            {
                static QSqlQuery s_query;
                bool v_query_status = s_query.prepare("select user_uri, user_id from yt_name_id where user_uri=:useruri");
                Q_UNUSED(v_query_status);
                v_query = &s_query;
            }
            v_query->bindValue(":useruri", v_rec->author_uri);
            v_query->exec();
            if(v_query->next())
            {
                v_rec->author_id = v_query->value( v_query->record().indexOf("user_id") ).toString();
            }
            else
            {
                BatchNetworkAccessManager v_bnam;
                QString v_url(
                            QString("http://gdata.youtube.com/feeds/api/users/%1").arg(v_rec->author_uri)
                            );
                ////qDebug() << "[v_url]" << v_url;
                QByteArray v_response = v_bnam.doGet(
                            v_url
                            ////QString("http://gdata.youtube.com/feeds/api/users/%1").arg(v_rec->author_uri)
                            );
                QDomDocument domDocumentUserId;
                if(XmlUtil::setXmlContent(domDocumentUserId, v_response))
                {
                    qDebug() << "xml parse error!(domDocumentUserId)";
                    // [/entry]
                    QDomElement v_rootUserId = domDocumentUserId.documentElement();
                    qDebug() << "[domDocumentUserId]" << domDocumentUserId.nodeName();
                    // [/entry/yt:username]
                    QDomNodeList v_entry_list = v_rootUserId.elementsByTagNameNS(
                                "http://gdata.youtube.com/schemas/2007", "username");
                    QDomElement v_userId_entry_2 = v_entry_list.at(0).toElement();
                    v_rec->author_id = v_userId_entry_2.text();
                    ////qDebug() << "[v_userId_entry_2.text()A]" << v_userId_entry_2.text();
                    if(v_rec->author.toLower() == v_rec->author_id)
                    {
                        v_rec->author_id = v_rec->author;
                    }
                    ////qDebug() << "[v_userId_entry_2.text()B]" << v_userId_entry_2.text();
                    static QSqlQuery *v_insert = NULL;
                    if(!v_insert)
                    {
                        static QSqlQuery s_insert;
                        bool v_insert_status = s_insert.prepare("insert into yt_name_id(user_uri, user_id) values(:uri, :userid)");
                        Q_UNUSED(v_insert_status)
                        v_insert = & s_insert;
                    }
                    v_insert->bindValue(":uri", v_rec->author_uri);
                    v_insert->bindValue(":userid" , v_rec->author_id);
                    v_insert->exec();
                }
            }
        }

        // [/feed/entry/yt:statistics(viewCount,favoriteCount)]
        //<yt:statistics xmlns:yt="http://gdata.youtube.com/schemas/2007" viewCount="450255" favoriteCount="1945"/>
        QDomNodeList v_stat_list = v_entry.elementsByTagNameNS("http://gdata.youtube.com/schemas/2007", "statistics");
        QDomElement v_stat = v_stat_list.at(0).toElement();
		v_rec->view_count = v_stat.attribute("viewCount").toLongLong();
		v_rec->favorite_count = v_stat.attribute("favoriteCount").toLongLong();

        //[/feed/entry/link(rel="self")]
        QDomNodeList v_self_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "link");
        for(int i=0; i<v_self_list.count(); i++)
        {
            if(!v_self_list.at(i).attributes().contains("rel")) continue;
            if(v_self_list.at(i).attributes().namedItem("rel").nodeValue() != "self") continue;
            QString v_self = v_self_list.at(i).attributes().namedItem("href").nodeValue();
            //qDebug() << "[v_self]" << v_self;
            v_rec->self = v_self;
        }
    }
	return result->size();
}

void YtManager::listUsersFavoriteWeb(QString a_user, T_VideoList *a_result)
{
	a_result->clear();
    int v_max_result = 20;

    QUrl v_url;
    v_url.setUrl(
            QString::fromLatin1("http://gdata.youtube.com/feeds/api/users/%1"
                                "/favorites?start-index=%2&max-results=%3")
            .arg(a_user).arg(1).arg(v_max_result)
            );
	QNetworkRequest v_top_request(v_url);
	if(!g_Env->youtube_auth_key.isEmpty())
	{
		v_top_request.setRawHeader("Authorization", QString("GoogleLogin auth=%1").arg(g_Env->youtube_auth_key).toLatin1().constData());
		v_top_request.setRawHeader("X-GData-Key", QString("key=%1").arg(g_Env->youtube_devl_key).toLatin1().constData());
	}
	g_Env->showMessage(v_top_request.url().toString());
    //QByteArray v_response = NetworkThreadRequest::doGet2(v_top_request);
    BatchNetworkAccessManager v_bnam;
    QByteArray v_response = v_bnam.doGet(v_top_request);
    qint64 v_totalResultCount = 0;
	XmlUtil::backupXmlBody(v_response, "listUsersFavoriteWeb.1");
    this->parseXmlForEntryList(v_response, a_result, &v_totalResultCount, true);
    qDebug() << "[v_totalResultCount]" << v_totalResultCount;
    int v_pageCount = (v_totalResultCount + (v_max_result-1)) / v_max_result;

    QList<QNetworkRequest> v_requestList;
    for(int v_pageNo=2; v_pageNo<=v_pageCount; v_pageNo++)
    {
        //int v_pageNo = i + 1;
        QUrl v_url;
        int v_startIndex = 1 + (v_max_result * (v_pageNo - 1));
        v_url.setUrl(
                QString::fromLatin1("http://gdata.youtube.com/feeds/api/users/%1"
                                    "/favorites?start-index=%2&max-results=%3")
                .arg(a_user).arg(v_startIndex).arg(v_max_result)
                );
        QNetworkRequest v_request;
        v_request.setUrl(v_url);
		if(!g_Env->youtube_auth_key.isEmpty())
		{
			v_request.setRawHeader("Authorization", QString("GoogleLogin auth=%1").arg(g_Env->youtube_auth_key).toLatin1().constData());
			v_request.setRawHeader("X-GData-Key", QString("key=%1").arg(g_Env->youtube_devl_key).toLatin1().constData());
		}
		g_Env->showMessage(v_request.url().toString());
		v_requestList.append(v_request);
	}
    //QList<QByteArray> v_responseList = NetworkThreadRequest::doGet2(v_requestList);
    ////BatchNetworkAccessManager v_bnam;
    QList<QByteArray> v_responseList = v_bnam.doGetList(v_requestList);
    for(int i=0; i<v_responseList.size(); i++)
    {
		T_VideoList v_result;
		QByteArray v_xml = v_responseList.at(i);
        if(v_xml.contains("fragile"))
        {
            XmlUtil::backupXmlBody(v_xml, "fragile.1");
        }
        this->parseXmlForEntryList(v_xml, &v_result, 0, true);
		a_result->append(&v_result);
    }
}


void YtManager::listPlaylistVideoWeb(QString a_playlist_id, T_VideoList *a_result)
{
	// http://gdata.youtube.com/feeds/api/playlists/C04C0F9A39F92146
	a_result->clear();
	int v_pageNo = 0;
	while(true)
	{
		v_pageNo++;
		QUrl v_url;
		int v_max_result = 20;
		int v_startIndex = 1 + (v_max_result * (v_pageNo - 1));
		v_url.setUrl(
				QString::fromLatin1("http://gdata.youtube.com/feeds/api/playlists/%1"
									"?start-index=%2&max-results=%3")
				.arg(a_playlist_id).arg(v_startIndex).arg(v_max_result)
				);
		QByteArray v_xml = m_nam->doGet(v_url);
		if (v_pageNo<=2) XmlUtil::backupXmlBody(v_xml, QString("listPlaylistVideoWeb.%1").arg(v_pageNo));
		T_VideoList v_result;
		this->parseXmlForEntryList(v_xml, &v_result);
		if (v_result.size()==0) break;
		a_result->append(&v_result);
	}
	for (int i=0; i<a_result->size(); i++)
	{
		if(a_result->value(i)->view_count == 0)
		{
			T_Video *v_rec = a_result->value(i);
			QString v_url_str = QString("http://gdata.youtube.com/feeds/api/videos/%1").arg(a_result->value(i)->id);
			QUrl v_url;
			v_url.setUrl(v_url_str);
            //QByteArray v_xml = NetworkThreadRequest::doGet2(v_url);
            QByteArray v_xml = m_nam->doGet(v_url);
            if(v_xml == "Video not found")
			{
				v_rec->view_count = -1;
			}
			else
			{
				QDomDocument domDocument2;
				if(XmlUtil::setXmlContent(domDocument2, v_xml))
				{
					QDomElement v_entry2 = domDocument2.documentElement();
					QDomNodeList v_stat_list2 = v_entry2.elementsByTagNameNS("http://gdata.youtube.com/schemas/2007", "statistics");
					QDomElement v_stat2 = v_stat_list2.at(0).toElement();
					v_rec->view_count = v_stat2.attribute("viewCount").toLongLong();
				}
			}
			qDebug() << v_rec->id << v_rec->view_count;
		}
	}
}

bool YtManager::dbVideoExists(QString a_id, QString a_tbl_name)
{
	static QMap<QString, QSqlQuery *> v_query_map;
	if(!v_query_map.contains(a_tbl_name))
	{
		QSqlQuery *v_new_query = new QSqlQuery;
		v_query_map.insert(a_tbl_name, v_new_query);
		v_query_map.value(a_tbl_name)->prepare(QString("select * from %1 where id=:id").arg(a_tbl_name));
	}
	QSqlQuery *v_query = v_query_map.value(a_tbl_name);
	v_query->bindValue(":id", a_id);
	v_query->exec();
	return v_query->next();
}

void YtManager::dbVideoInsert(T_Video * a_rec, QString a_tbl_name)
{
	qDebug() << "[YtManager::dbVideoInsert()]" << a_tbl_name; // << a_rec;
	qDebug() << "[insert(1)]";
	QSqlQuery v_query_body;
	QSqlQuery *v_query = &v_query_body;
	v_query->prepare(
			QString(
#if 0x0
                    "insert into %1 ( id, self, page, pos, title, author, pubdate, view_count, favorite_count, view_rank, view_ts) "
                    "values         (:id,:self,:page,:pos,:title,:author,:pubdate,:view_count,:favorite_count,:view_rank,:view_ts)"
#else
                    "insert into %1 ( id, self, page, pos, title, author, author_uri, author_id, pubdate, view_count, favorite_count, view_rank, view_ts) "
                    "values         (:id,:self,:page,:pos,:title,:author,:author_uri,:author_id,:pubdate,:view_count,:favorite_count,:view_rank,:view_ts)"
#endif
                    ).arg(a_tbl_name)
            );
#if 0x1
    v_query->bindValue(":id", a_rec->id);
    v_query->bindValue(":self", a_rec->self);
    v_query->bindValue(":page", a_rec->page);
    v_query->bindValue(":pos", a_rec->pos);
    v_query->bindValue(":title", a_rec->title);
    v_query->bindValue(":author", a_rec->author);
    v_query->bindValue(":author_uri", a_rec->author_uri);
    v_query->bindValue(":author_id", a_rec->author_id);
    v_query->bindValue(":pubdate", a_rec->pubdate);
    v_query->bindValue(":view_count", a_rec->view_count);
    v_query->bindValue(":favorite_count", a_rec->favorite_count);
    v_query->bindValue(":view_rank", a_rec->view_rank);
    v_query->bindValue(":view_ts", a_rec->view_ts);
#else
	for(int i=0; i<a_rec->metaObject()->propertyCount(); i++)
	{
		QMetaProperty v_prop = a_rec->metaObject()->property(i);
		if(!v_prop.isWritable()) continue;
		if(strcmp(v_prop.name(), "objectName")==0) continue;
		QString v_prop_name = QString::fromLatin1(v_prop.name());
		v_query->bindValue(QString(":")+v_prop_name, a_rec->property(v_prop.name()));
	}
#endif
	qDebug() << "[insert(3)]";
    bool v_status = v_query->exec();
    qDebug() << "[insert(4)]" << v_status;
    if(!v_status)
    {
        qDebug() << v_query->lastError();
    }
}

bool YtManager::dbVideoSelect(QString a_id, QString a_tbl_name, T_Video *a_rec)
{
	static QMap<QString, QSqlQuery *> v_query_map;
	if(!v_query_map.contains(a_tbl_name))
	{
		QSqlQuery *v_new_query = new QSqlQuery;
		v_query_map.insert(a_tbl_name, v_new_query);
		v_query_map.value(a_tbl_name)->prepare(QString("select * from %1 where id=:id").arg(a_tbl_name));
	}
	QSqlQuery *v_query = v_query_map.value(a_tbl_name);
	v_query->bindValue(":id", a_id);
	v_query->exec();
	if(!v_query->next())
	{
		a_rec->id = "";
		return false;
	}
	for(int i=0; i<a_rec->metaObject()->propertyCount(); i++)
	{
		QMetaProperty v_prop = a_rec->metaObject()->property(i);
		if(strcmp(v_prop.name(), "objectName")==0) continue;
		if(v_query->record().indexOf(v_prop.name()) == -1) continue;
		a_rec->setProperty(v_prop.name(), v_query->value(v_query->record().indexOf(v_prop.name())));
	}
	return true;
}

void YtManager::dbVideoDelete(QString a_id, QString a_tbl_name)
{
	static QMap<QString, QSqlQuery *> v_query_map;
	if(!v_query_map.contains(a_tbl_name))
	{
		QSqlQuery *v_new_query = new QSqlQuery;
		v_query_map.insert(a_tbl_name, v_new_query);
		v_query_map.value(a_tbl_name)->prepare(QString("delete from %1 where id=:id").arg(a_tbl_name));
	}
	QSqlQuery *v_query = v_query_map.value(a_tbl_name);
	v_query->bindValue(":id", a_id);
	v_query->exec();
}
